函数 bs2rv:
len是字串的长度,lb和ub是每个变量的下界和上界,lbin和ubin指明表示范围中是否包含边界,0不包括,1包括。
函数 crtbp:
函数 crtrp:
适应度计算
函数 ranking:
其实我对这个函数没了解得太深刻,不过我觉得这是一种变比技术。将原先的适应度值压缩到一定的范围,而且目标值越大,分配的适应度值越小。例如 A=[1;2;3;4;2;3];
ranking(A)= 2.0000 1.4000 0.6000 0 1.4000 0.6000,所以如果是求最大值,就得-A,求最小值就直接A就可以了,因为目标值越大分配的适应度越小,目标值越小,分配的适应度越大。ranking的结果FitV只在select选择的时候有用到,这只是一种个体选择概率的常用分配方法之一
关于个体选择概率的常用分配方法参考:http://wenku.baidu.com/link?url=U9fHrBvJg2YMac-7ckdcLGs9EtXgxzmux6ahLrYlMZWiJBfbzekkdtaKERaD0ZO6hsY56RzTTiIQds4Vn0fysPKSaYSPcpQ1qFcLxp22LWy
选择
高级函数 select:
SUBPOP是指子代种群的个数
rws: 轮盘赌选择
sus:
关于选择方法的介绍及比较参考:http://wenku.baidu.com/link?url=fyc9LUjso9IJmYhEKd7fnLl_25CsTdGZEm1CyCtHaDj2DtYe5K9IQCcY7DhcHD-dTlsgdgjobsImdOQUr4MmKm9CytLBsUU1oLCBLyn4uVO
交叉
高级函数 recombin:
chrom是待交叉的种群,recopt是交叉概率,subpop是一个决定子种群个数的可选参数,默认是1,chrom中所有子种群的大小必须一致。
recdis:
recint:
reclin:
xovdp:
Xovdprs:
Xovmp:
Xovsh:
Xovshrs:
Xovsp:
Xovsprs:
变异
高级函数 mutate:
NewChorm=mutate(MUT_F, OldChorm, FieldDR, MutOpt)
NewChorm=mutate(MUT_F, OldChorm, FieldDR, MutOpt, SUBPOP)
MUT_F为包含低级变异函数的字符串,例如mut, mutbga, recmut
mut:
NewChrom=mut(OldChorm, Pm, BaseV)
mutbga:
NewChrom=mutbga(OldChorm, FieldDR)
recmut:
重插入
函数 reins:
Chorm, 父代种群,SelCh子代种群
其他函数
矩阵复试函数 rep:
使用案例:
clc
clear all
close all
%% 画出函数图
figure(1);
hold on;
lb=1;ub=2; %函数自变量范围【1,2】
ezplot('sin(10*pi*X)/X',[lb,ub]); %画出函数曲线
xlabel('自变量/X')
ylabel('函数值/Y')
%% 定义遗传算法参数
NIND=40; %个体数目
MAXGEN=20; %最大遗传代数
PRECI=20; %变量的二进制位数
GGAP=0.95; %代沟
px=0.7; %交叉概率
pm=0.01; %变异概率
trace=zeros(2,MAXGEN); %寻优结果的初始值
FieldD=[PRECI;lb;ub;1;0;1;1]; %区域描述器
Chrom=crtbp(NIND,PRECI); %初始种群
%% 优化
gen=0; %代计数器
X=bs2rv(Chrom,FieldD); %计算初始种群的十进制转换
ObjV=sin(10*pi*X)./X; %计算目标函数值
while gen<MAXGEN
FitnV=ranking(ObjV); %分配适应度值
SelCh=select('sus',Chrom,FitnV,GGAP); %选择,随机遍历选择
SelCh=recombin('xovsp',SelCh,px); %重组,单点交叉
SelCh=mut(SelCh,pm); %变异
X=bs2rv(SelCh,FieldD); %子代个体的十进制转换
ObjVSel=sin(10*pi*X)./X; %计算子代的目标函数值
[Chrom,ObjV]=reins(Chrom,SelCh,1,1,ObjV,ObjVSel); %重插入子代到父代,得到新种群
%chrom是父代种群,selch是子代,1,子种群数目都是1,1,基于适应度的选择,用子代代替父代适应度最小的个体
X=bs2rv(Chrom,FieldD);
gen=gen+1; %代计数器增加
%获取每代的最优解及其序号,Y为最优解,I为个体的序号
[Y,I]=min(ObjV);
trace(1,gen)=X(I); %记下每代的最优值
trace(2,gen)=Y; %记下每代的最优值
end
figure(2);
plot(trace(1,:),trace(2,:),'bo'); %画出每代的最优点
grid on;
plot(X,ObjV,'b*'); %画出最后一代的种群
title('每代的最优点')
%此时x中存的是最后一代种群的所有个体的十进制值
hold off
%% 画进化图
figure(3);
plot(1:MAXGEN,trace(2,:));
grid on
xlabel('遗传代数')
ylabel('解的变化')
title('进化过程')
bestY=trace(2,end);
bestX=trace(1,end);
fprintf(['最优解:\nX=',num2str(bestX),'\nY=',num2str(bestY),'\n'])
运行结果:
案例2:
clc
clear all
close all
%% 画出函数图
figure(1);
lbx=-2;ubx=2; %函数自变量x范围【-2,2】
lby=-2;uby=2; %函数自变量y范围【-2,2】
ezmesh('y*sin(2*pi*x)+x*cos(2*pi*y)',[lbx,ubx,lby,uby],50); %画出函数曲线
hold on;
%% 定义遗传算法参数
NIND=40; %个体数目
MAXGEN=50; %最大遗传代数
PRECI=20; %变量的二进制位数
GGAP=0.95; %代沟
px=0.7; %交叉概率
pm=0.01; %变异概率
trace=zeros(3,MAXGEN); %寻优结果的初始值
FieldD=[PRECI PRECI;lbx lby;ubx uby;1 1;0 0;1 1;1 1]; %区域描述器
Chrom=crtbp(NIND,PRECI*2); %初始种群
%% 优化
gen=0; %代计数器
XY=bs2rv(Chrom,FieldD); %计算初始种群的十进制转换
X=XY(:,1);Y=XY(:,2);
ObjV=Y.*sin(2*pi*X)+X.*cos(2*pi*Y); %计算目标函数值
while gen<MAXGEN
FitnV=ranking(-ObjV); %分配适应度值,因为这里是求最大值,所以改成了负的
SelCh=select('sus',Chrom,FitnV,GGAP); %选择
SelCh=recombin('xovsp',SelCh,px); %重组,单点交叉
SelCh=mut(SelCh,pm); %变异
XY=bs2rv(SelCh,FieldD); %子代个体的十进制转换
X=XY(:,1);Y=XY(:,2);
ObjVSel=Y.*sin(2*pi*X)+X.*cos(2*pi*Y); %计算子代的目标函数值
[Chrom,ObjV]=reins(Chrom,SelCh,1,1,-ObjV,-ObjVSel); %重插入子代到父代,得到新种群,因为此处是求最大值,所以目标值都是负的
% 1,子种群的个数是1,1,基于适应度的选择,子代代替父代中适应度最小的个体
XY=bs2rv(Chrom,FieldD);
gen=gen+1; %代计数器增加
%获取每代的最优解及其序号,Y为最优解,I为个体的序号
[Y,I]=max(ObjV);
trace(1:2,gen)=XY(I,:); %记下每代的最优值
trace(3,gen)=Y; %记下每代的最优值
end
plot3(trace(1,:),trace(2,:),trace(3,:),'bo'); %画出每代的最优点
grid on;
plot3(XY(:,1),XY(:,2),ObjV,'bo'); %画出最后一代的种群
hold off
%% 画进化图
figure(2);
plot(1:MAXGEN,trace(3,:));
grid on
xlabel('遗传代数')
ylabel('解的变化')
title('进化过程')
bestZ=trace(3,end);
bestX=trace(1,end);
bestY=trace(2,end);
fprintf(['最优解:\nX=',num2str(bestX),'\nY=',num2str(bestY),'\nZ=',num2str(bestZ),'\n'])
结果与上一个相似,就不贴图了,这里只想补充一点:谢菲尔的工具箱中的ranking函数是依据目标函数的值进行适应度分配的,目标函数的值越大,适应度分配越小,目标函数的值越小,适应度分配的结果就越大,我们选择的时候是依据适应度值越大选择的概率就越大的方式去选择,所以当求最小值的时候,直接将目标函数值代入ranking函数中即可,而在求最大值的时候要代入负的目标值,这样最大值就变成了最小值可以得到最大的适应度分配值。另外,ranking函数的结果只在select中会用到,插入的时候用的是目标值。